<?php

class Upload extends TPage {
//<editor-fold defaultstate="collapsed" desc="Verifica Usuario Logueado">
  /**
   * determina si el usuario esta logueado en el sistema
   * @author VSR, 01/01/2011
   */
  private function usuarioLogueado() {
    $estaLogueado = false;
    try {
      $session = new THttpSession;
      $session->open();
      $oUsuario = $session[Usuario::NOMBRE_ENTIDAD];
      if (isset($oUsuario)) {
        $estaLogueado = true;
      }
    } catch (Exception $e) {
      $estaLogueado = false;
    }
    return $estaLogueado;
  }

  /**
   * redirecciona al login
   * @author VSR, 01/01/2011
   */
  private function redireccionarLogin() {
    $this->Response->redirect($this->Service->constructUrl("Admin"));
  }

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Metodos Privados">
  /**
   * graba archivo en base datos si es que no existe
   * @param <type> $idArchivo
   * @param <type> $arrArchivos
   * @author VSR, 22/04/2011
   */
  private function grabarArchivoTemporalEnBaseDatos(&$idArchivo, &$arrArchivos) {
    try {
      $arrArchivos = Utilidades::obtenerSessionPorNombre(Archivo::SESION_UPLOAD);
      $oUsuario = Utilidades::obtenerSessionPorNombre(Usuario::NOMBRE_ENTIDAD);
      if(is_null($arrArchivos)) {
        $arrArchivos = array();
        $totalRegistros = 0;
      } else {
        $totalRegistros = count($arrArchivos);
      }

      $nombreArchivo = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';
      //quita caracteres especiales
      $nombreArchivo = Archivo::reemplazarCaracteresEspeciales($nombreArchivo);
      $contentType = $_FILES["file"]["type"];
      $extension = $this->obtenerExtensionArchivo($nombreArchivo);
      $arrExisteArchivo = Utilidades::arrayRowFilter($arrArchivos, "Nombre == '$nombreArchivo'");
      //si el archivo no existe en sesion entonces lo graba en base datos
      if(count($arrExisteArchivo) == 0) {
        $idUsuario = $oUsuario->getId();
        $idArchivo = Archivo::grabaEnBaseDatos($idUsuario, $nombreArchivo, $extension, $contentType);
        if(is_null($idArchivo) ) {
          throw new Exception("No se pudo grabar el archivo en base datos");
        } else {
          $arrArchivos[$totalRegistros]["IdArchivo"] = $idArchivo;
          $arrArchivos[$totalRegistros]["Nombre"] = $nombreArchivo;
          $arrArchivos[$totalRegistros]["Tamano"] = 0;
          $arrArchivos[$totalRegistros]["Completado"] = "0";
          Utilidades::grabarSessionPorNombre(Archivo::SESION_UPLOAD, $arrArchivos);
        }
      } else {
        $idArchivo = $arrExisteArchivo[0]["IdArchivo"];
      }
    } catch (Exception $e) {
      die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "No se pudo grabar archivo en base datos"}, "id" : "id"}');
    }
  }


  /**
   * graba el archivo en el repositorio
   * @param <type> $idArchivo
   * @param <type> $arrArchivos
   * @author VSR, 22/04/2011
   */
  private function grabarArchivoEnRepositorio($idArchivo, $arrArchivos) {
    try {
      // HTTP headers for no cache etc
      header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
      header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
      header("Cache-Control: no-store, no-cache, must-revalidate");
      header("Cache-Control: post-check=0, pre-check=0", false);
      header("Pragma: no-cache");

      //crea la ruta de la carpeta de destino
      $targetDir = "[repositorio]/".$idArchivo;
      $tamano = 0;

      // 5 minutes execution time
      @set_time_limit(5 * 60);

      // Uncomment this one to fake upload time
      // Get parameters
      $chunk = isset($_REQUEST["chunk"]) ? $_REQUEST["chunk"] : 0;
      $chunks = isset($_REQUEST["chunks"]) ? $_REQUEST["chunks"] : 0;
      $fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';

      // Clean the fileName for security reasons
      $fileName = Archivo::reemplazarCaracteresEspeciales($fileName);

      // Make sure the fileName is unique but only if chunking is disabled
      if ($chunks < 2 && file_exists($targetDir."/".$fileName)) {
        $fileName = $this->crearNombreArchivoRepetido($targetDir, $fileName);
      }

      // Create target dir
      if (!file_exists($targetDir))
        @mkdir($targetDir);

      // Look for the content type header
      if (isset($_SERVER["HTTP_CONTENT_TYPE"]))
        $contentType = $_SERVER["HTTP_CONTENT_TYPE"];

      if (isset($_SERVER["CONTENT_TYPE"]))
        $contentType = $_SERVER["CONTENT_TYPE"];

      // Handle non multipart uploads older WebKit versions didn't support multipart in HTML5
      if (strpos($contentType, "multipart") !== false) {
        if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
          // Open temp file
          $tamano = $_FILES['file']['size'];
          $out = fopen($targetDir."/".$fileName, $chunk == 0 ? "wb" : "ab");
          if ($out) {
            // Read binary input stream and append it to temp file
            $in = fopen($_FILES['file']['tmp_name'], "rb");

            if ($in) {
              while ($buff = fread($in, 4096))
                fwrite($out, $buff);
            } else
              die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
            fclose($in);
            fclose($out);
            @unlink($_FILES['file']['tmp_name']);
          } else
            die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
        } else
          die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}');
      } else {
        // Open temp file
        $out = fopen($targetDir."/".$fileName, $chunk == 0 ? "wb" : "ab");
        if ($out) {
          // Read binary input stream and append it to temp file
          $in = fopen("php://input", "rb");

          if ($in) {
            while ($buff = fread($in, 4096))
              fwrite($out, $buff);
          } else
            die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');

          fclose($in);
          fclose($out);
        } else
          die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
      }

      //va sumando los tamaños de los archivos subidos
      $totalRegistros = count($arrArchivos);
      $tamanoActual = $arrArchivos[$totalRegistros-1]["Tamano"];
      $arrArchivos[$totalRegistros-1]["Tamano"] = $tamanoActual + $tamano;

      //cuando termina de subir todas las partes del archivo, lo marca como completado
      if($chunk == $chunks-1) {
        $arrArchivos[$totalRegistros-1]["Completado"] = "1";
      }
      Utilidades::grabarSessionPorNombre(Archivo::SESION_UPLOAD, $arrArchivos);

      // Return JSON-RPC response
      die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}');

    } catch (Exception $e) {
      die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "No se pudo grabar archivo en disco"}, "id" : "id"}');
    }
  }


//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Metodos Compartidos">
  /**
   * construye nuevo nombre si es que el archivo ya existe en el disco
   * @param <type> $directorio
   * @param <type> $nombreArchivo
   * @return <type>
   * @author VSR, 22/04/2011
   */
  public static function crearNombreArchivoRepetido($directorio, $nombreArchivo) {
    if (file_exists($directorio."/".$nombreArchivo)) {
      $ext = strrpos($nombreArchivo, '.');
      $fileName_a = substr($nombreArchivo, 0, $ext);
      $fileName_b = substr($nombreArchivo, $ext);

      $count = 1;
      while (file_exists($directorio."/".$fileName_a.'_'.$count. $fileName_b))
        $count++;

      $nuevoNombre = $fileName_a.'_'.$count.$fileName_b;
    } else {
      $nuevoNombre = $nombreArchivo;
    }
    return $nuevoNombre;
  }

  /**
   * obtiene la extension del archivo
   * @param <type> $nombreArchivo
   * @return string
   * @author VSR, 22/04/2011
   */
  public static function obtenerExtensionArchivo($nombreArchivo) {
    $extension = "";
    try {
      if(!Utilidades::isNullOrEmpty($nombreArchivo)) {
        $ext = strrpos($nombreArchivo, '.');
        $fileName_a = substr($nombreArchivo, 0, $ext);
        $fileName_b = substr($nombreArchivo, $ext);
        $extension = str_replace(".","",$fileName_b);
      }
    } catch (Exception $e) {
      $extension = "";
    }
    return $extension;
  }
//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Eventos Controles">
  public function onLoad($param) {
    parent::onLoad($param);
    //si no esta conectado entonces lo redirecciona al login
    if (!$this->usuarioLogueado()) {
      $this->redireccionarLogin();
    }

    $idArchivo = "0";
    $arrArchivos = array();
    $this->grabarArchivoTemporalEnBaseDatos($idArchivo, $arrArchivos);
    $this->grabarArchivoEnRepositorio($idArchivo, $arrArchivos);
  }

//</editor-fold>

}

?>
